package gui.addrecipe;


import gui.overview.OverviewPanel;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.border.TitledBorder;

import org.jdom.JDOMException;

import start.Config;
import start.Start;

import xml.XMLRecipeReader;
import xml.XMLRecipeSaver;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Zusammenfassende Klasse, implementiert alle weiteren Layout-Klassen zum Aufbau des Einfuegen-Panels
 * @author Dominik Korittki
 */
public class AddRecipe extends JPanel {
	
	/** Linkes Teilpanel. Grundlegende Informationen wie Namen, Kategorien, etc. */
	private static AddRecipe_Basic leftPanel;
	
	/** Rechts oberes Teilpanel. Enthält die Zutatenliste. */
	private AddRecipeRightTopPanel rightTopPanel;
	
	/** Rechts unteres Teilpanel. Enthält das Bild, Bewertung, Anzahl Personen */
	private AddRecipeRightBottomPanel rightBottomPanel;
	
	/** Unteres Panel zum Speichern des Rezepts oder Resetten der Textfelder */
	private JPanel bottomPanel;
	
	/** Weitergabe des Informationen zum Speichern in einer XML-Datei */
	private static XMLRecipeSaver xmlsaver;
	
	/** Auslesen von bereits gespeicherten XML Informationen. Wichtig zur Bestimmung der Rezept-ID */
	private static XMLRecipeReader xmlreader;
	
	/** Button zum Speichern eines Rezepts */
	private JButton btnSpeichern;
	
	/** Button zum Zuruecksetzen aller Textinformationen in den Feldern */
	private JButton btnAbbrechen;
	
	/** Button zum Drucken des Rezeptes, wurde noch nicht implementiert und ist unsichtbar */
	private JButton btnDrucken;
	
	/** Serial Version ID */
	private static final long serialVersionUID = 1L;
	

	/**
	 * Erstellt des Panel
	 * @throws IOException Eingabe Ausgabe Fehler 
	 * @throws JDOMException XML Fehler
	 */
	public AddRecipe() throws JDOMException, IOException {
		xmlsaver = new XMLRecipeSaver(Start.getRezeptexml());
		xmlreader = new XMLRecipeReader(Start.getRezeptexml());
		
		createGUI();
		
		btnSpeichern.addActionListener(new ActionListener() {
			/*
			 * XML Liste speichern
			 */
			@Override public void actionPerformed(ActionEvent arg0) {
				String name = leftPanel.getName();
				String kategorie1 = "";
				if(!leftPanel.getKategorie1().equals("keine")) {
					kategorie1 = leftPanel.getKategorie1();
				}
				String kategorie2 = "";
				if(!leftPanel.getKategorie2().equals("keine")) {
					kategorie2 = leftPanel.getKategorie2();
				}
				String kategorie3 = "";
				if(!leftPanel.getKategorie3().equals("keine")) {
					kategorie3 = leftPanel.getKategorie3();
				}
				String zubereitungText = leftPanel.getZubereitung();
				ArrayList<String> zutaten = rightTopPanel.getZutaten();
				int bewertung = rightBottomPanel.getBewertung();
				int anzahlPersonen = rightBottomPanel.getAnzahlPersonen();
				String tags = rightBottomPanel.getTags();
				
				//Hoechste Id bestimmen + Bildnamen festlegen
				int id = 0;
				try {
					id = xmlreader.highestID() + 1;
				} catch (JDOMException e2) {
					JOptionPane.showMessageDialog(Start.getDefWindow(),
						    "Technischer Fehler",
						    "Konnte ID nicht entnehmen, technischer Fehler!", JOptionPane.ERROR_MESSAGE);
					if(Config.debugMode()) e2.printStackTrace();
				} catch (IOException e2) {
					JOptionPane.showMessageDialog(Start.getDefWindow(),
						    "Datei nicht gefunden",
						    "Konnte die Datei mit den Rezepten nicht finden. \n" +
						    "Ein Neustart sollte das Problem beheben.", JOptionPane.ERROR_MESSAGE);
					if(Config.debugMode()) e2.printStackTrace();
				}
				String imgname;
				String thumbname;
				if(rightBottomPanel.getImg() != null) {
					imgname = "image_" + id + ".jpg";
					thumbname = "thumbnail_" + id + ".jpg";
				} else {
					imgname = "";
					thumbname = "";
				}
				
				//Pop Up Meldung
				int i = checkUserInput(name, kategorie1, kategorie2, kategorie3, zubereitungText, zutaten);
				if(i == 0) {
					try {
						if(rightBottomPanel.getImg() != null) {
							rightBottomPanel.getImg().writeSmallImg(Config.getBildpfad() + imgname);
							rightBottomPanel.getImg().writeThumbnail(Config.getThumbpfad() + thumbname);
						}
						
					} catch (IOException e1) {
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Konnte die Bilddateien nicht speichern. Sind die Schreibrechte gesetzt?",
							    "IO Fehler", JOptionPane.ERROR_MESSAGE);
					}
					
					boolean doubleentries = true;
					try {
						doubleentries = xmlsaver.add(id, name, zutaten, kategorie1, kategorie2, kategorie3, zubereitungText, imgname, thumbname, bewertung, anzahlPersonen, tags);
					} catch (IOException e) {
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "IOFehler",
							    "Konnte die XML-Datei nicht speichern. Sind die Schreibrechte gesetzt?", JOptionPane.ERROR_MESSAGE);
						if(Config.debugMode()) e.printStackTrace();
					}
					catch (JDOMException e) {
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Allgemeiner Fehler",
							    "Es trat ein allgemeiner Fehler. Bitte suchen sie nach neueren Softwareversionen\n"
							   +"oder kontaktieren Sie die Programmierer.", JOptionPane.ERROR_MESSAGE);
						if(Config.debugMode()) e.printStackTrace();
					}
					if(!doubleentries) { //auf doppelte Eintraege pruefen
						JOptionPane.showMessageDialog(Start.getDefWindow(),
								"Es gibt bereits einen Eintrag mit diesen Namen",
								"Fehler",
								JOptionPane.ERROR_MESSAGE);
						
					} else {
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Rezept wurde erfolgreich hinzugefügt",
							    "Erfolgreich hinzugefügt", JOptionPane.INFORMATION_MESSAGE);
						leftPanel.reset();
						rightTopPanel.reset();
						rightBottomPanel.reset();
					}
					
				} else {
					switch (i) {
					case 1: //Keinen Rezeptnamen angegeben
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Bitte gebe einen Namen für das Rezept an",
							    "Rezept nicht gespeichert", JOptionPane.ERROR_MESSAGE);
						break;
					case 2: //Keine Kategorien angegeben
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Bitte wähle zumindest eine Kategorie aus",
							    "Rezept nicht gespeichert", JOptionPane.ERROR_MESSAGE);
						break;
					case 3: //Keine Zubereitung angegeben
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Bitte schreib unter Zubereitung etwas zu deinem Gericht",
							    "Rezept nicht gespeichert", JOptionPane.ERROR_MESSAGE);
						break;
					case 4: //Keine Zutaten angegeben (was sinnlos waere)
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Bitte füge zumindest eine Zutat hinzu. Sonst wäre das Rezept ja sinnlos ;-)",
							    "Rezept nicht gespeichert", JOptionPane.ERROR_MESSAGE);
						break;

					default:
						break;
					}
				}
				
			}
		});
		
	}
	
	/**
	 * Bearbeiten-Fenster. Fuellt Felder mit Textinformationen anhand einer Rezept-ID
	 * @param actID ID des anzuzeigenden Rezeptes
	 * @throws JDOMException XML Fehler
	 * @throws IOException Eingabe Ausgabe Fehler
	 */
	public AddRecipe(final int actID) throws JDOMException, IOException {
		xmlreader = new XMLRecipeReader(Start.getRezeptexml());
		xmlsaver = new XMLRecipeSaver(Start.getRezeptexml());
		
		String name = "";
		List<String> zutatenList = new ArrayList<String>();
		zutatenList.add("Keine Einträge");
		String zubereitungText = "";
		String imgName = "";
		String thumbName = "";
		int anzahlPersonen = 1;
		String category1 = "";
		String category2 = "";
		String category3 = "";
		int bewertung = 0;
		String tags = "";
		
		
		//Auslesen der XML
		if(actID >= 0) {
			name = xmlreader.getName(actID);
			zutatenList = xmlreader.getIngredients(actID);
			zubereitungText = xmlreader.getPreperationTxt(actID);
			imgName = xmlreader.getImageName(actID);
			thumbName = xmlreader.getThumbnailName(actID);
			anzahlPersonen = xmlreader.getPersAmount(actID);
			category1 = xmlreader.getCategory1(actID);
			category2 = xmlreader.getCategory2(actID);
			category3 = xmlreader.getCategory3(actID);
			bewertung = xmlreader.getRating(actID);
			tags = xmlreader.getTags(actID);
		}
		
		createGUI();
		btnAbbrechen.setVisible(false);
		
		if(actID >= 0) {
			//Left Panel Texte setzen
			leftPanel.getNameTF().setText(name);
			leftPanel.getKategorie1CMB().setSelectedItem(category1);
			leftPanel.getKategorie2CMB().setSelectedItem(category2);
			leftPanel.getKategorie3CMB().setSelectedItem(category3);
			leftPanel.getTxtZubereitungArea().setText(zubereitungText);
			rightTopPanel.getModel().clear();
			
			//Right Top Panel Texte setzen
			for(String comp : zutatenList) {
				rightTopPanel.getModel().addElement(comp);
			}
			
			//Right Bottom Panel Texte setzen
			if(!thumbName.isEmpty() && !imgName.isEmpty()) {
				File tempThumb = new File(Config.getThumbpfad() + thumbName);
				File tempImg = new File(Config.getBildpfad() + imgName);
				if(tempImg.exists() && tempThumb.exists()) {
					rightBottomPanel.changePreviewImageOnly(ImageIO.read(new File(Config.getThumbpfad() + thumbName)));
				}
			}
			rightBottomPanel.setBewertung(bewertung);
			rightBottomPanel.getStars().setStars(bewertung);
			rightBottomPanel.getTxtArea().setText(tags);
			rightBottomPanel.getSpinner().setValue(anzahlPersonen);
		} else {
			btnSpeichern.setEnabled(false);
		}
		
		/* Rezept ueberschreiben */
		btnSpeichern.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				String name = leftPanel.getName();
				String kategorie1 = "";
				if(!leftPanel.getKategorie1().equals("keine")) {
					kategorie1 = leftPanel.getKategorie1();
				}
				String kategorie2 = "";
				if(!leftPanel.getKategorie2().equals("keine")) {
					kategorie2 = leftPanel.getKategorie2();
				}
				String kategorie3 = "";
				if(!leftPanel.getKategorie3().equals("keine")) {
					kategorie3 = leftPanel.getKategorie3();
				}
				String zubereitungText = leftPanel.getZubereitung();
				ArrayList<String> zutaten = rightTopPanel.getZutaten();
				int bewertung = rightBottomPanel.getBewertung();
				int anzahlPersonen = rightBottomPanel.getAnzahlPersonen();
				String tags = rightBottomPanel.getTags();
				
				//Pop Up Meldung
				int i = checkUserInput(name, kategorie1, kategorie2, kategorie3, zubereitungText, zutaten);
				if(i == 0) {
					//Bild speichern
					String imgname = "image_" + actID + ".jpg";
					String thumbname = "thumbnail_" + actID + ".jpg";
					if(rightBottomPanel.getImg() == null && rightBottomPanel.getImgChanged()) { //Wenn kein Bild mehr existieren soll
						try {
							new File(Config.getBildpfad() + "image_" + actID + ".jpg").delete();
							new File(Config.getThumbpfad() + "thumbnail_" + actID + ".jpg").delete();
						} catch(SecurityException e) {} //nichts tun
						imgname = "";
						thumbname = "";
					} else if(rightBottomPanel.getImg() != null){ //Wenn ein neues Bild ausgewaehlt wurde
						try {
							rightBottomPanel.getImg().writeSmallImg(Config.getBildpfad() + imgname);
							rightBottomPanel.getImg().writeThumbnail(Config.getThumbpfad() + thumbname);
						} catch (IOException e1) {
							JOptionPane.showMessageDialog(Start.getDefWindow(),
								    "Konnte die Bilddateien nicht speichern. Sind die Schreibrechte gesetzt?",
								    "IO Fehler", JOptionPane.ERROR_MESSAGE);
						}
					}		
					
					//Textinformationen speichern
					try {
						xmlsaver.replace(String.valueOf(actID), name, zutaten, kategorie1, kategorie2, kategorie3, zubereitungText, imgname, thumbname, bewertung, anzahlPersonen, tags);
					} catch (IOException e) {
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Konnte die XML-Datei nicht speichern. Sind die Schreibrechte gesetzt?",
							    "IO Fehler", JOptionPane.ERROR_MESSAGE);
						if(Config.debugMode()) e.printStackTrace();
					}
					catch (JDOMException e) {
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Allgemeiner Fehler",
							    "Es trat ein allgemeiner Fehler. Bitte suchen sie nach neueren Softwareversionen\n"
							   +"oder kontaktieren Sie die Programmierer.", JOptionPane.ERROR_MESSAGE);
						if(Config.debugMode()) e.printStackTrace();
					}
					
					JOptionPane.showMessageDialog(getParent(),
						    "Änderungen gespeichert",
						    "Erfolg", JOptionPane.INFORMATION_MESSAGE);
					
					try {
						OverviewPanel.getTable().updateFromXML(xmlreader);
					} catch (JDOMException e) {
						if(Config.debugMode()) e.printStackTrace();
					} catch (IOException e) {
						if(Config.debugMode()) e.printStackTrace();
					}
				} else {
					switch (i) {
					case 1: //Keinen Rezeptnamen angegeben
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Bitte gebe einen Namen für das Rezept an",
							    "Rezept nicht gespeichert", JOptionPane.ERROR_MESSAGE);
						break;
					case 2: //Keine Kategorien angegeben
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Bitte wähle zumindest eine Kategorie aus",
							    "Rezept nicht gespeichert", JOptionPane.ERROR_MESSAGE);
						break;
					case 3: //Keine Zubereitung angegeben
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Bitte schreib unter Zubereitung etwas zu deinem Gericht",
							    "Rezept nicht gespeichert", JOptionPane.ERROR_MESSAGE);
						break;
					case 4: //Keine Zutaten angegeben (was sinnlos waere)
						JOptionPane.showMessageDialog(Start.getDefWindow(),
							    "Bitte füge zumindest eine Zutat hinzu. Sonst wäre das Rezept ja sinnlos ;-)",
							    "Rezept nicht gespeichert", JOptionPane.ERROR_MESSAGE);
						break;

					default:
						break;
					}
				}
			}
		});
	}
	
	/**
	 * Initiiert und platziert GUI Elemente
	 * @throws JDOMException XML Fehler
	 * @throws IOException Eingabe Ausgabe Fehler
	 */
	public void createGUI() throws JDOMException, IOException {
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[]{0, 200, 0};
		gridBagLayout.columnWeights = new double[]{1.0, 0.0, Double.MIN_VALUE};
		gridBagLayout.rowWeights = new double[]{1.0, 1.0, 0.0};
		setLayout(gridBagLayout);
		
		
		/*-----------------------------------------
		 * linkes Panel
		 *---------------------------------------*/
		leftPanel = new AddRecipe_Basic();
		leftPanel.setBorder(new TitledBorder(null, "Hinzufügen", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		GridBagConstraints gbc_leftPanel = new GridBagConstraints();
		gbc_leftPanel.insets = new Insets(10, 0, 5, 5);
		gbc_leftPanel.gridheight = 2;
		gbc_leftPanel.fill = GridBagConstraints.BOTH;
		gbc_leftPanel.gridx = 0;
		gbc_leftPanel.gridy = 0;
		add(leftPanel, gbc_leftPanel);
		
		/*-----------------------------------------
		 * rechtes oberes Panel Panel
		 *---------------------------------------*/
		rightTopPanel = new AddRecipeRightTopPanel();
		rightTopPanel.setBorder(new TitledBorder(null, "Zutatenliste", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		GridBagConstraints gbc_rightTopPanel = new GridBagConstraints();
		gbc_rightTopPanel.insets = new Insets(10, 0, 5, 0);
		gbc_rightTopPanel.fill = GridBagConstraints.BOTH;
		gbc_rightTopPanel.gridx = 1;
		gbc_rightTopPanel.gridy = 0;
		add(rightTopPanel, gbc_rightTopPanel);
		
		/*-----------------------------------------
		 * rechtes unteres Panel Panel
		 *---------------------------------------*/
		rightBottomPanel = new AddRecipeRightBottomPanel();
		rightBottomPanel.setBorder(new TitledBorder(null, "Weiteres", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		GridBagConstraints gbc_rightBottomPanel = new GridBagConstraints();
		gbc_rightBottomPanel.insets = new Insets(0, 0, 5, 0);
		gbc_rightBottomPanel.fill = GridBagConstraints.BOTH;
		gbc_rightBottomPanel.gridx = 1;
		gbc_rightBottomPanel.gridy = 1;
		add(rightBottomPanel, gbc_rightBottomPanel);
		
		/*-----------------------------------------
		 * Unteres Panel
		 *---------------------------------------*/
		bottomPanel = new JPanel();
		GridBagConstraints gbc_bottomPanel = new GridBagConstraints();
		gbc_bottomPanel.insets = new Insets(0, 0, 5, 0);
		gbc_bottomPanel.fill = GridBagConstraints.BOTH;
		gbc_bottomPanel.gridx = 0;
		gbc_bottomPanel.gridy = 2;
		gbc_bottomPanel.gridwidth = 2;
		add(bottomPanel, gbc_bottomPanel);
		
		
		btnSpeichern = new JButton("Speichern", new ImageIcon(Start.getImgs().getSave()));
		btnAbbrechen = new JButton("Zurücksetzen", new ImageIcon(Start.getImgs().getCloseSmall()));
		btnDrucken = new JButton("Drucken");
		btnDrucken.setVisible(false);
		btnDrucken.setEnabled(false);
		bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
		bottomPanel.add(btnSpeichern);
		bottomPanel.add(btnAbbrechen);
		bottomPanel.add(btnDrucken);	
		
		btnAbbrechen.addKeyListener(new KeyListener() {
			@Override public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
					leftPanel.reset();
					rightTopPanel.reset();
					rightBottomPanel.reset();
				}		
			}
			@Override public void keyReleased(KeyEvent e) {}
			@Override public void keyTyped(KeyEvent e) {}
		});
		btnAbbrechen.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				leftPanel.reset();
				rightTopPanel.reset();
				rightBottomPanel.reset();
			}
		});

	}
	
	/**
	 * Prueft die Eingaben auf Vollstaendigkeit
	 * @param name Rezeptname
	 * @param kat1 erste Kategorie
	 * @param kat2 zweite Kategorie
	 * @param kat3 dritte Kategorie
	 * @param zubereitung Zubereitungstext des Rezepts
	 * @param zutaten Zutatenliste
	 * @return 0 = alles okay, 1 = Kein Name, 2 = keine Kategorie, 3 = kein Zubereitungstext, 4 = Keine Zutaten
	 */
	private int checkUserInput(String name, String kat1, String kat2, String kat3, String zubereitung, ArrayList<String> zutaten) {
		if(name.isEmpty()) return 1;
		if(kat1.isEmpty() && kat2.isEmpty() && kat3.isEmpty()) return 2;
		if(zubereitung.isEmpty()) return 3;
		if(zutaten.isEmpty()) return 4;
		
		return 0;
	}
	
	/**
	 * Liefert das linke JPanel zurueck
	 * @return linkes Panel vom Typ AddRecipe_Basic, erweitert ein JPanel
	 */
	public static AddRecipe_Basic getLeftPanel() {
		return leftPanel;
	}

	/**
	 * Liefert das rechte obere JPanel zurueck
	 * @return rechtes oberes Panel vom Typ AddRecipeRightTopPanel, erweitert ein JPanel
	 */
	public AddRecipeRightTopPanel getRightTopPanel() {
		return rightTopPanel;
	}

	/**
	 * Liefert das rechte untere JPanel zurueck
	 * @return rechtes unteres Panel vom Typ AddRecipeRightBottomPanel, erweitert ein JPanel
	 */
	public AddRecipeRightBottomPanel getRightBottomPanel() {
		return rightBottomPanel;
	}

	/**
	 * Liefert das untere JPanel zurueck
	 * @return Unteres Panel vom Typ JPanel
	 */
	public JPanel getBottomPanel() {
		return bottomPanel;
	}
}
